﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RapidAddition.FIXDataDictionary;
using RapidAddition.FIXObjectModel.FIX42;

namespace LiquidTrading.RapidAdditionHelper.Storage.LiquidView
{
    public sealed class FtenStorage : IStorage,  IDisposable
    {
        public FtenStorage(string clientName)
        {
            ClientName = clientName;
            m_Linq = new LiquidViewLinqDataContext();
        }

        LiquidViewLinqDataContext m_Linq;
        public string ClientName { get; set; }

        #region IStorage Members

        public void ProcessExecutionReportFIX42(RapidAddition.FIXDataDictionary.CFIXDataDictionary dic, RapidAddition.FIXEngine.CFIXMessage exec)
        {
            if (dic.Version == RapidAdditionHelper.Clients.FIXClient.FIX42)
            {
                CMsgExecutionReport msg = new CMsgExecutionReport(dic, exec);

                Console.WriteLine("ExecTransType: " + msg.ExecTransType.ToString() + " - ExecType: " + msg.ExecType.ToString());

                if (msg.ExecTransType.Value == EExecTransType.eNew
                    && (msg.ExecType.Value == EExecType.ePartialfill || msg.ExecType.Value == EExecType.ePartialfill))
                {

                    CFIXTagValue tag;

                    string FtenVenue = String.Empty;
                    if (exec.TagValuesParsed.TryGetValue(9863, out tag))
                    {
                        FtenVenue = tag.Value;
                    }
                    else
                    {
                        m_Linq.ExceptionHandlerThrow("F10DropCopy", "Failed to decode FtenVenue(9863) from MsgExecutionReport(8) - " + exec.Message, null);
                        return;
                    }

                    bool TradeLiquidityIndicator;
                    if (exec.TagValuesParsed.TryGetValue(9730, out tag))
                    {
                        TradeLiquidityIndicator = (tag.Value == "R") ? true : false;
                        //TradeLiquidityIndicator = ; // A added Liq, R removed liq, D dark trade, X onward routed trade
                    }
                    else
                    {
                        //m_Linq.ExceptionHandlerThrow("F10DropCopy", "Failed to decode TradeLiquidityIndicator(9730) from MsgExecutionReport(8) - " + exec.Message, null);
                        //return;
                        TradeLiquidityIndicator = true;
                    }

                    string ContraBroker;
                    if (exec.TagValuesParsed.TryGetValue(375, out tag))
                    {
                        ContraBroker = tag.Value;
                    }
                    else
                    {
                        if (msg.ExecRptCntraBrkrs.Count > 0)
                        {
                            ContraBroker = msg.ExecRptCntraBrkrs[0].ContraBroker;
                        }
                        else
                        {
                            ContraBroker = String.Empty;
                        }
                    }

                    string Currency = msg.Currency;
                    decimal price = (decimal)msg.LastPx.Value;
                    if (Currency.ToUpper() == "GBX" || msg.Currency == "GBp")
                    {
                        Currency = "GBP";
                        price = price / 100;
                    }

                    int result = m_Linq.ImportTradeByUMTF(
                        ClientName,
                        msg.ClOrdID,
                        msg.ExecID,
                        FtenVenue,
                        msg.OrderID,
                        msg.ExecID,
                        msg.Account != String.Empty ? msg.Account : "DEFAULT",
                        Currency != String.Empty ? Currency : null,
                        msg.Symbol,
                        msg.Side == ESide.eBuy ? (long)msg.LastQty.Value : -(long)msg.LastQty.Value,
                        price,
                        msg.TransactTime.Value,
                        ContraBroker,
                        TradeLiquidityIndicator,
                        false,
                        false,
                        String.Empty,
                        msg.Text,
                        false,
                        null,
                        null,
                        null,
                        exec.TargetCompID != String.Empty ? exec.TargetCompID : null);

                    if (result == 0)
                    {
                        // trade inserted
                    }
                    else if (result == 1)
                    {
                        m_Linq.ExceptionHandlerThrow("F10DropCopy", "Filtered broker trade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -1)
                    {
                        m_Linq.ExceptionHandlerThrow("F10DropCopy", "Failed (general) on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -2)
                    {
                        m_Linq.ExceptionHandlerThrow("F10DropCopy", "Failed to find StockId from UMTF code " + msg.Symbol + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -3)
                    {
                        m_Linq.ExceptionHandlerThrow("F10DropCopy", "Failed to find ExchangeMIC of " + FtenVenue + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -4)
                    {
                        m_Linq.ExceptionHandlerThrow("F10DropCopy", "Failed to find default Local Listing and Currency for " + msg.Symbol + " on " + FtenVenue + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -5)
                    {
                        m_Linq.ExceptionHandlerThrow("F10DropCopy", "Failed to complete PutGtrade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -6)
                    {
                        m_Linq.ExceptionHandlerThrow("F10DropCopy", "Failed to complete PutTrade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                }
                else
                {
                    Console.WriteLine("Unhandled - ExecTransType: " + msg.ExecTransType.ToString() + " - ExecType: " + msg.ExecType.ToString());
                }
            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            m_Linq.Dispose();
        }

        #endregion

        #region IStorage Members

        public void ProcessState(RapidAddition.FIXEngine.CFIXSession session, RapidAddition.FIXEngine.EFIXSessionState state)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IStorage Members

        public void LogGeneral(string category, string message)
        {
            throw new NotImplementedException();
        }

        public void LogException(string category, string message)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IStorage Members


        public void ProcessExecutionReportFIX50(CFIXDataDictionary dic, RapidAddition.FIXEngine.CFIXMessage exec)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

}
